local skynet = require "skynet"
local msg_center = require "race.msg_center"
local proto_manager = require "common.proto_manager"
local MessageType = require "common.message_type"
local time_manager = require "common.time_manager"
local race_manager = require "race.race_manager"
local service_helper = require "common.service_helper"
local player_manager = require "race.player_manager"

local function onRegisterRaceRoomReq(data)

    local msg = {
        result = proto_manager.ErrorCode_Successed,
        match_id = data.match_id,
    }

    local room = race_manager.getRoom(data.match_id)
    if room then
        msg.result = proto_manager.errcode("ErrorCode_SystemError")
        skynet.error("onRegisterRaceRoomReq already had roomid:" .. tostring(data.match_id))
    else
        room = race_manager.createRoom(data.match_id,data.players)
        if room then

            local players = {}
            room:foreachPlayers(function(player)
                local p = {
                    open_id = player:getOpenID(),
                    index = player:getIndex(),
                    token = player:getToken(),
                }
                table.insert(players,p)
            end)
            msg.players = players
            msg.ip,msg.port = msg_center.getAddress()

        else
            msg.result = proto_manager.errcode("ErrorCode_SystemError")
            skynet.error("onRegisterRaceRoomReq createRoom room failed! roomid:" .. tostring(data.match_id))
        end
    end

    service_helper.send2Match(MessageType.RegisterRaceRoomResp,msg)

end
msg_center.setDefaultMessageHandler(MessageType.RegisterRaceRoomReq,onRegisterRaceRoomReq)


local function parseProtoMessage(fd,t,data)
    local req,err = proto_manager.decode(t,data)
    if err then
        skynet.error("decode " .. t  .. " err:" .. err .. " fd:" .. fd .. " traceback:" .. debug.traceback())
        return nil
    end
    return req
end

local function onRaceHandshake(fd,id,data)

    local req = parseProtoMessage(fd,"MessageRaceHandshake",data)
    if not req then
        return
    end

    race_manager.onHandshake(fd,req)

end
msg_center.setClientMessageHandler(proto_manager.message_id("MessageId_RaceHandshake"),onRaceHandshake)

local function onInputFrame(fd,id,data)

    local req = parseProtoMessage(fd,"MessageInputFrame",data)
    if not req then
        return
    end

    local player = player_manager.getPlayerByFd(fd)
    if not player then
        skynet.error("onInputFrame|not find player fd:" .. tostring(fd))
        return
    end

    race_manager.onInputFrame(player:getRoomID(),player:getOpenID(),req.frame)

end
msg_center.setClientMessageHandler(proto_manager.message_id("MessageId_InputFrame"),onInputFrame)

local function onDestroyRaceRoom(data)

    local room = race_manager.getRoom(data.room_id)
    if room then
        race_manager.onRaceEnd(data.room_id)
    else
        skynet.error("onDestroyRaceRoom|not find room id:" .. tostring(data.room_id))
    end

end
msg_center.setDefaultMessageHandler(MessageType.DestroyRaceRoom,onDestroyRaceRoom)

local function onGetFramesReq(data)

    local player = player_manager.getPlayerByOpenID(data.open_id)
    if not player then
        skynet.error("onGetFramesReq|not find player open_id:" .. data.open_id)
        return
    end

    local msg = {
        result = proto_manager.ErrorCode_Successed,
        room_id = data.room_id,
        frames = {},
    }

    local tempFrames = race_manager.getFrames(data.room_id)
    if tempFrames then
        msg.frames = tempFrames
    else
        msg.result = proto_manager.errcode("ErrorCode_NotFindRaceRoom")
        skynet.error("onGetFramesReq|not find room id:" .. tostring(data.room_id))
    end

    player:sendTcpMessage("MessageId_GetFramesResp","MessageGetFramesResp",msg)

end
msg_center.setDefaultMessageHandler(MessageType.MessageId_GetFramesReq,onGetFramesReq)